/**
 * 选择器 工具
 */

import RandomUtil from "./RandomUtil";
import BaseUtil from "./BaseUtil";

/** @noSelf **/
export default class SelectUtil {
    static cache: { [id: string]: any } = {}

    static getAnHero(playerIndex: number): unit {

        let cacheUnitHandle = SelectUtil.cache["getAnHero:" + playerIndex];
        //todo 如果删除单位后  此handle可能是另一个新单位
        if (IsHandle(cacheUnitHandle)) {
            return cacheUnitHandle;
        }

        //获取玩家一个英雄
        GroupClear(tempGroup);
        GroupEnumUnitsOfPlayer(tempGroup, Player(playerIndex), null)
        for (let i = 0; i <= 1000000; i++) {
            let unitHandle = FirstOfGroup(tempGroup)
            if (!IsHandle(unitHandle)) {
                break
            }
            if (IsUnitType(unitHandle, UNIT_TYPE_HERO)
                && GetHeroStr(unitHandle, false) > 1
                && !IsUnitType(unitHandle, UNIT_TYPE_PEON)
                && !IsUnitType(unitHandle, UNIT_TYPE_SUMMONED)
                && !IsUnitIllusion(unitHandle)
                && !IsUnitHidden(unitHandle)) {

                //
                SelectUtil.cache["getAnHero:" + playerIndex] = unitHandle;
                return unitHandle;
            }
            GroupRemoveUnit(tempGroup, unitHandle)
        }
        return null;
    }

    static getAnEnemy(playerIndex: number): unit {
        GroupClear(tempGroup);
        GroupEnumUnitsInRect(tempGroup, bj_mapInitialPlayableArea, null)
        let player = Player(playerIndex);
        let result = null;
        while (true) {
            let unit = FirstOfGroup(tempGroup);
            if (!IsHandle(unit)) {
                break
            }
            GroupRemoveUnit(tempGroup, unit)
            if (IsUnitEnemy(unit, player)) {
                result = unit
                //随机挑选一个敌人
                if (RandomUtil.nextInt(1, 100) < 20) {
                    break;
                }
            }
        }
        return result;
    }


    /**
     * 遍历单位周围的敌方单位
     */
    static forEnemyUnitsInRange(center: unit, radius: number, callback: (unit: unit) => void): void {
        GroupClear(tempGroup);
        let x: number = GetUnitX(center)
        let y: number = GetUnitY(center)
        GroupEnumUnitsInRange(tempGroup, x, y, radius, null);
        let myPlayer = GetOwningPlayer(center)
        for (let i = 0; i <= 1000000; i++) {
            let unitHandle = FirstOfGroup(tempGroup)
            if (!IsHandle(unitHandle)) {
                break
            }
            if (IsUnitEnemy(unitHandle, myPlayer)) {
                callback(unitHandle)
            }
            GroupRemoveUnit(tempGroup, unitHandle)
        }
    }

    static forUnitsInRange(x: number, y: number, radius: number, callback: (unit: unit) => void): void {
        GroupClear(tempGroup);
        GroupEnumUnitsInRange(tempGroup, x, y, radius, null);
        BaseUtil.SForGroup(tempGroup, callback)
    }

    static forAllUnits(callback: (unit: unit) => void, unitType?: string): void {
        GroupClear(tempGroup);
        GroupEnumUnitsInRect(tempGroup, bj_mapInitialPlayableArea, null);
        if (unitType) {//如果指定类型存在 则按指定类型遍历
            let unitTypeNum = FourCC(unitType)
            for (let i = 0; i <= 1000000; i++) {
                let unitHandle = FirstOfGroup(tempGroup)
                if (!IsHandle(unitHandle)) {
                    break
                }
                if (unitTypeNum == GetUnitTypeId(unitHandle)) {
                    callback(unitHandle)
                }
                GroupRemoveUnit(tempGroup, unitHandle)
            }
        } else {
            BaseUtil.SForGroup(tempGroup, callback)
        }
    }

    static forPlayerUnits(callback: (unit: unit) => void, playerIndex: number, unitType?: string) {
        GroupClear(tempGroup);
        GroupEnumUnitsOfPlayer(tempGroup, Player(playerIndex), null)
        if (unitType) {//如果指定类型存在 则按指定类型遍历
            let unitTypeNum = FourCC(unitType)
            for (let i = 0; i <= 1000000; i++) {
                let unitHandle = FirstOfGroup(tempGroup)
                if (!IsHandle(unitHandle)) {
                    break
                }
                if (unitTypeNum == GetUnitTypeId(unitHandle)) {
                    callback(unitHandle)
                }
                GroupRemoveUnit(tempGroup, unitHandle)
            }
        } else {
            BaseUtil.SForGroup(tempGroup, callback)
        }

    }


    /**
     * 遍历所有敌人 Enemy
     * whoseEnemy 谁的敌人 （默认遍历玩家1的敌人）
     * @param callback
     */
    static forAllEnemyUnits(callback: (unit: unit) => void, whoseEnemy: player = Player(0)): void {
        GroupClear(tempGroup);
        GroupEnumUnitsInRect(tempGroup, bj_mapInitialPlayableArea, null);
        for (let i = 0; i <= 1000000; i++) {
            let unitHandle = FirstOfGroup(tempGroup)
            if (!IsHandle(unitHandle)) {
                break
            }
            if (IsUnitEnemy(unitHandle, whoseEnemy)) {
                callback(unitHandle)
            }
            GroupRemoveUnit(tempGroup, unitHandle)
        }
    }


}
